<?
/*-- Project Introduce --*/


/**
 * What's this Class ?
 *
 * @author		alee
 * @access		public
 */
class JCAT_Patch
{	
	/**
	 * Description
	 *
	 * @access	public
	 * @param	$Parameter
	 * @return	void
	 */
	public function LoadPatchFile($sPathFile)
	{
		$aPatchContent = JCAT_String::CreateFromFile($sPathFile) ;
		return self::LoadPatch($aPatchContent) ;
	}
	
	/**
	 * Description
	 *
	 * @access	public
	 * @param	$aPathContent		JCAT_String
	 * @return	void
	 */
	public function LoadPatch(JCAT_String $aPathContent)
	{		
		$aIterator = $aPathContent->MatchResult(self::$sRegExp) ;
		if(!$aIterator->GetResultCount())
		{
			return ;
		}
		
		for ( $aIterator->Last(); !$aIterator->IsDone(); $aIterator->Previous() )
		{
			$sFilePath = $aIterator->Current(self::$nRegExpGrpFilePath) ;
			$nPosInPatch = $aIterator->CurrentPos() ;	
			
			// 路径有 “(delete)” 后缀
			$arrPathRes = array() ;
			if( preg_match("/^(.+)(\\(deleted\\))$/i",$sFilePath,$arrPathRes) )
			{
				$sFilePath = trim($arrPathRes[1]) ;
				$aFile = new JCAT_PatchFile($sFilePath) ;
				$aFile->SetDeleting(true) ;
			}
			
			// 
			else 
			{
				$aFile = new JCAT_PatchFile($sFilePath) ;
							
				$nPartPathLen = strlen($aIterator->Current()) ;
				
				// 取得 modify 部分
				$sModifyContent = $aPathContent->SubStr($nPosInPatch + $nPartPathLen) ;
				$aFile->ParseModifies($sModifyContent) ;
				
			}

			$aPathContent->Replace('',$nPosInPatch) ;
			$this->arrFiles[] = $aFile ;
		}		
		
	}
	
	/**
	 * Description
	 *
	 * @access	public
	 * @param	$Parameter
	 * @return	void
	 */
	public function Apply($sApplyPath)
	{
		foreach ($this->arrFiles as $aChangeFile)
		{
			$aChangeFile->Apply($sApplyPath) ;
		}
	}
	
	/**
	 * 测试是否存取权限
	 *
	 * @access	public
	 * @param 	$arrOutUnaccessFiles
	 * @return	bool
	 */
	public function TestAccessMode($sApplyPath,array & $arrOutUnaccessFiles)
	{
		$arrOutUnaccessFiles = array() ;
		
		foreach ($this->arrFiles as $aChangeFile)
		{
			if( !$aChangeFile->TestAccessMode($sApplyPath) )
			{
				$arrOutUnaccessFiles[] = JCAT_Global::TidyPath($sApplyPath.$aChangeFile->GetFilePath()) ;
			}
		}
		
		return empty($arrOutUnaccessFiles) ;
	}
	
	/**
	 * Description
	 *
	 * @access	public
	 * @return	JCAT_IIterator
	 */
	public function CreateChangingFileIter()
	{
		return new JCAT_ArrayIterator($this->arrFiles) ;
	}
		
	/**
	 * Description
	 * 
	 * @access	private
	 * @static
	 * @var		string
	 */
	static private $sRegExp = "/#
Index:\s([^\\n]+(\(deleted\))?)\\n#
=+(\\n|$)#
/xis" ;
	
	static private $nRegExpGrpFilePath = 1 ;
	
	
	/**
	 * Description
	 * 
	 * @access	private
	 * @var		array
	 */
	private $arrFiles = array() ;

}

?>